package com.ejy.commons.utils;

import com.github.pagehelper.Page;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * TODO
 *
 * @Author WangYan
 * @Date 2021/6/10 10:17
 */
public class BeanUtils extends org.springframework.beans.BeanUtils {

    /**
     * 复制 所有属性
     */
    public static <S, T> T copyAToB(S source, T target) {
        if (null == source) {
            return null;
        }
        if (null == target) {
            throw new NullPointerException("target bean is null!");
        }
        copyProperties(source, target);
        return target;
    }

    /**
     * 复制 所有属性
     */
    public static <S, T> T copyAToB(S source, Class<T> targetClass) {
        if (null == source) {
            return null;
        }
        if (null == targetClass) {
            throw new NullPointerException("target bean is null!");
        }
        try {
            T t = targetClass.newInstance();
            copyProperties(source, t);
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        throw new RuntimeException("targetClass copy error !");
    }

    /**
     * 复制 非空属性
     */
    public static <S, T> T copyAToBNotNull(S source, T target) {
        if (null == source) {
            return null;
        }
        if (null == target) {
            throw new NullPointerException("target bean is null!");
        }
        copyProperties(source, target, getNullPropertyNames(source));
        return target;
    }

    /**
     * 复制 非空属性
     */
    public static <S, T> T copyAToBNotNull(S source, Class<T> targetClass) {
        if (null == source) {
            return null;
        }
        if (null == targetClass) {
            throw new NullPointerException("target bean is null!");
        }
        try {
            T t = targetClass.newInstance();
            copyProperties(source, t, getNullPropertyNames(source));
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        throw new RuntimeException("targetClass copy error !");
    }

    /**
     * 复制集合
     *
     * @Author WangYan
     * @Date 2021/6/10 10:26
     */
    public static <S, T> List<T> copyAListToBList(List<S> source, Class<T> targetClass) {
        if (null == targetClass) {
            throw new NullPointerException("target bean is null!");
        }

        List<T> targets;
        if (source instanceof Page) {
            targets = new Page<>();
            copyAToB(source, targets);
        } else {
            targets = new ArrayList<>();
        }
        if (CollectionUtils.isEmpty(source)) {
            return targets;
        }
        source.stream().forEach(s -> {
            try {
                T t = targetClass.newInstance();
                targets.add((T) (copyAToB(s, t)));
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        return targets;
    }

    /**
     * 获取空属性名称
     *
     * @Author WangYan
     * @Date 2021/6/10 10:28
     */
    public static String[] getNullPropertyNames(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<String>();
        for (java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) {
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

//    <!-- pageHelper 分页插件 -->
//        <dependency>
//            <groupId>com.github.pagehelper</groupId>
//            <artifactId>pagehelper-spring-boot-starter</artifactId>
//            <version>1.2.12</version>
//            <exclusions>
//                <exclusion>
//                    <groupId>org.mybatis</groupId>
//                    <artifactId>mybatis</artifactId>
//                </exclusion>
//            </exclusions>
//        </dependency>
}
